/**
 * @author Created by qiush on 2017-06-09.
 */

const {app, ipcMain} = require('electron');
const path = require('path');

const fileUtil = require('./fileUtil');
const dialogUtil = require('./dialogUtil');
const resourceUtil = require('./resourceUtil');
const designResourceUtil = require('./designResourceUtil');

// 组件的保存路径
const viewsPath = path.join(app.getPath('userData'), 'views');

const views = [];

function _parseView(fileData) {
  try {
    return JSON.parse(fileData);
  } catch (e) {
    dialogUtil.showError(e);
  }
}

/**
 * 读取组件文件内容
 * @param {*} filename 组件文件的文件名
 */
async function _loadView(filename) {
  // 读取文件
  const fileData = await fileUtil.readFile(path.join(viewsPath, filename));

  // 解析成json
  const fileContent = _parseView(fileData);
  if (!fileContent) {
    return false;
  }

  // 处理资源
  resourceUtil.addResources(fileContent.resources);

  // 返回组件的内容
  return fileContent.view;
}

async function _getViewFilename() {
  if (!(await fileUtil.isExist(viewsPath))) {
    await fileUtil.mkdir(viewsPath);
  }

  return await dialogUtil.showSave({
    title: '保存为组件',
    filters: [{
      name: '组件文件',
      extensions: ['view']
    }],
    defaultPath: path.join(viewsPath, '组件名称')
  });
}

const viewFileUtil = {
  async load(isForceReload) {
    if (views.length > 0 && !isForceReload) {
      return views;
    }

    if (!(await fileUtil.isExist(viewsPath))) {
      await fileUtil.mkdir(viewsPath);
    }

    // 获取组件目录下的文件名列表
    const viewFileNames = await fileUtil.readDir(viewsPath);
    if (!viewFileNames || viewFileNames.length === 0) {
      // 没有文件, 则直接返回了
      return views;
    }

    // 读取每个文件的内容
    const viewPromises = viewFileNames
      .filter(name => name.endsWith('.view'))
      .map(async name => {
        // 读取文件内容
        const view = await _loadView(name);
        return {
          name: name.replace(/\.view$/i, ''),
          view
        };
      });

    const resolvedViews = await Promise.all(viewPromises);
    // 去掉可能为false 的那些数据
    const resolvedTrueViews = resolvedViews.filter(view => !!view.view);

    views.length = 0; // 先清空原来已经添加的组件
    views.push(...resolvedTrueViews);

    return views;
  },

  async save(design) {
    if (!design) {
      return Promise.reject('不是正确的设计内容...');
    }

    const designResources = designResourceUtil.findDesignResources(design);

    // 其实和保存设计类似, 不过这里只需要保存根组件
    const viewFileContent = {
      view: design.root,
      resources: designResources
    };

    const viewFilename = await _getViewFilename();
    return fileUtil.writeFile(viewFilename, viewFileContent);
  }
};

function _doLoadViews(sender, isForceReload) {
  viewFileUtil.load(isForceReload)
    .then(views => {
      // 将加载到的组件发给页面
      sender.send('load-views', views);
    })
    .catch(dialogUtil.showError);
}

/** 页面发送加载组件的消息时 */
ipcMain.on('load-views', event => {
  // 加载组件
  _doLoadViews(event.sender);
});

/** 页面发送保存组件的消息时 */
ipcMain.on('save-as-view', (event, design) => {
  // 将设计的根组件保存为组件
  viewFileUtil.save(design)
    .then((filePath) => {
      // 保存了组件之后, 直接重新加载一下
      _doLoadViews(event.sender, true);

      // 也要通知一下页面文件已保存, 更新一下标题栏的名称
      const filename = fileUtil.filename(filePath);
      event.sender.send('saved-file', design.id, filename)
    })
    .catch(dialogUtil.showError);
});

module.exports = viewFileUtil;
